package com.repair.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.repair.entity.User;
import com.repair.entity.RepairmanLocation;
import com.repair.mapper.UserMapper;
import com.repair.mapper.RepairmanLocationMapper;
import com.repair.service.UserService;
import com.repair.service.RepairmanLocationService;
import com.repair.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Date;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public UserServiceImpl(UserMapper userMapper, PasswordEncoder passwordEncoder) {
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
    }

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RepairmanLocationService repairmanLocationService;

    @Override
    public User findByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    @Transactional
    public void register(User user) {
        // 检查用户名是否已存在
        if (userMapper.selectByUsername(user.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        // 设置默认角色为普通用户
        user.setRole(0);
        // 设置默认状态为启用
        user.setStatus(1);

        userMapper.insert(user);
    }

    @Override
    public String login(String username, String password) {
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        if (user.getStatus() == 0) {
            throw new RuntimeException("账号已被禁用");
        }

        return jwtUtil.generateToken(user);
    }

    @Override
    @Transactional
    public void updateProfile(User user) {
        User existingUser = getById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        existingUser.setPhone(user.getPhone());
        existingUser.setEmail(user.getEmail());
        existingUser.setUpdateTime(LocalDateTime.now());
        updateById(existingUser);
    }

    @Override
    @Transactional
    public void changePassword(Long userId, String oldPassword, String newPassword) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        userMapper.updateById(user);
    }

    @Override
    public long count() {
        return super.count();
    }

    @Override
    public long countRepairmen() {
        return count(new LambdaQueryWrapper<User>()
                .eq(User::getRole, 2)
                .eq(User::getStatus, 1));
    }

    @Override
    public List<User> getRepairmen() {
        return userMapper.selectRepairmen();
    }

    @Override
    public List<Map<String, Object>> getRepairmanLocations() {
        // TODO: 实现获取维修工位置的方法
        return null;
    }

    @Override
    @Transactional
    public void updateUserStatus(Long id, Integer status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        user.setStatus(status);
        userMapper.updateById(user);
    }

    @Override
    public User updateStatus(Long id, Integer status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        user.setStatus(status);
        userMapper.updateById(user);
        return user;
    }

    @Override
    public void delete(Long id) {
        userMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void toggleUserStatus(Long id) {
        User user = getById(id);
        if (user != null) {
            user.setStatus(user.getStatus() == 1 ? 0 : 1);
            user.setUpdateTime(LocalDateTime.now());
            updateById(user);
        }
    }

    @Override
    @Transactional
    public void toggleRepairmanStatus(Long id) {
        User repairman = getById(id);
        if (repairman != null && "REPAIRMAN".equals(repairman.getRole())) {
            repairman.setStatus(repairman.getStatus() == 1 ? 0 : 1);
            repairman.setUpdateTime(LocalDateTime.now());
            updateById(repairman);
        }
    }

    @Override
    public User getByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public void updateRepairmanStatus(Long repairmanId, Integer status) {
        User repairman = userMapper.selectById(repairmanId);
        if (repairman != null && repairman.getRole() == 2) {
            repairman.setStatus(status);
            repairman.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(repairman);
        }
    }

    @Override
    public void updatePassword(Long userId, String newPassword) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setPassword(passwordEncoder.encode(newPassword));
            user.setUpdateTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
    }
}